﻿using Newtonsoft.Json.Linq;
using NLog;
using Persistence.Core;
using QueryDataLogic.Core;
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text;

namespace PersistenceDataLogic.Core
{
    public class OperationDishes
    {
        private static Logger logger = LogManager.GetCurrentClassLogger();
        PersistenceData pd = new PersistenceData();
        QueryData qd = new QueryData();
        BasicInfo bi = new BasicInfo();

        /// <summary>
        /// 判断是否存在用户点菜信息
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="date"></param>
        /// <param name="districtID"></param>
        /// <param name="dishesID"></param>
        /// <param name="dishesClassID"></param>
        /// <param name="dbName"></param>
        /// <returns></returns>
        private bool IsUserDishes(int userID, string date, int districtID, int dishesID, int dishesClassID, string dbName)
        {
            JArray ja = new JArray();
            try
            {
                SqlCommand comm = new SqlCommand()
                {
                    CommandText = "select id,userID,dishesID,[date],remark,districtID,hallID from UserDishes " +
                    "where dishesID = @dishesID and districtID = @districtID and [date] = @date and userID = @userID " +
                    "and dishesClassID = @dishesClassID "
                };

                comm.Parameters.AddWithValue("@userID", userID);
                comm.Parameters.AddWithValue("@date", date);
                comm.Parameters.AddWithValue("@dishesID", dishesID);
                comm.Parameters.AddWithValue("@districtID", districtID);
                comm.Parameters.AddWithValue("@dishesClassID", dishesClassID);

                ja = qd.GetData(comm, dbName);

                if (ja.Count > 0)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Console.Write(ex);
            }
            return false;
        }

        /// <summary>
        /// 获取用户当日当前类别的点菜的数量
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="date"></param>
        /// <param name="districtID"></param>
        /// <param name="dishesClassID"></param>
        /// <param name="dbName"></param>
        /// <returns></returns>
        private int CountUserDishes(int userID, string date, int districtID, int dishesClassID, string dbName)
        {
            JArray ja = new JArray();
            int result = 0;
            try
            {
                SqlCommand comm = new SqlCommand()
                {
                    CommandText = "select count(id) as count from UserDishes " +
                    "where districtID = @districtID and [date] = @date and userID = @userID and dishesClassID = @dishesClassID "
                };

                comm.Parameters.AddWithValue("@userID", userID);
                comm.Parameters.AddWithValue("@date", date);
                comm.Parameters.AddWithValue("@districtID", districtID);
                comm.Parameters.AddWithValue("@dishesClassID", dishesClassID);

                ja = qd.GetData(comm, dbName);

                if (ja.Count > 0)
                {
                    result = (int)ja[0]["count"];
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Console.Write(ex);
            }
            return result;
        }

        /// <summary>
        /// 获取当前菜品类别的最大点菜数量
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="date"></param>
        /// <param name="districtID"></param>
        /// <param name="dishesClassID"></param>
        /// <param name="dbName"></param>
        /// <returns></returns>
        private int MaxDishesClass(int dishesClassID, string dbName)
        {
            JArray ja = new JArray();
            int result = 0;
            try
            {
                SqlCommand comm = new SqlCommand()
                {
                    CommandText = "select qty from DishesClass " +
                    "where id = @dishesClassID "
                };

                comm.Parameters.AddWithValue("@dishesClassID", dishesClassID);
                ja = qd.GetData(comm, dbName);

                if (ja.Count > 0)
                {
                    result = (int)ja[0]["qty"];
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Console.Write(ex);
            }
            return result;
        }

        /// <summary>
        /// 点菜
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="dishesID"></param>
        /// <param name="dishesClassID"></param>
        /// <param name="date"></param>
        /// <param name="districtID"></param>
        /// <param name="hallID"></param>
        /// <param name="remark"></param>
        /// <param name="dbName"></param>
        /// <returns></returns>
        private JObject AddDishes(int userID, int dishesID, int dishesClassID, string date, int districtID, int hallID, string remark, string dbName)
        {
            JObject joResult = new JObject();
            try
            {
                int resultLine = 0;
                SqlCommand comm = new SqlCommand
                {
                    CommandText = "INSERT INTO UserDishes(UserID,DishesID,DishesClassID,Date,DistrictID,hallID,remark) VALUES(@UserID,@DishesID,@DishesClassID,@Date,@DistrictID,@hallID,@remark)"
                };

                comm.Parameters.AddWithValue("@UserID", userID);
                comm.Parameters.AddWithValue("@DishesID", dishesID);
                comm.Parameters.AddWithValue("@DishesClassID", dishesClassID);
                comm.Parameters.AddWithValue("@Date", date);
                comm.Parameters.AddWithValue("@DistrictID", districtID);
                comm.Parameters.AddWithValue("@hallID", hallID);
                comm.Parameters.AddWithValue("@remark", remark);
                resultLine = pd.ExeSqlCode(comm, dbName);
                if (resultLine > 0)
                {
                    Console.Write("\n[" + date + "]: 数据库：" + dbName + " 区域ID：" + districtID + "\n用户ID：" + userID + " 点菜成功，菜品ID：" + dishesID + "\n");
                    logger.Info("\n[" + date + "]: 数据库：" + dbName + " 区域ID：" + districtID + "\n用户ID：" + userID + " 点菜成功，菜品ID：" + dishesID + "\n");
                    joResult["message"] = "点菜成功";
                    joResult["data"] = resultLine;
                    joResult["state"] = true;
                }
                else
                {
                    joResult["message"] = "点菜失败";
                    joResult["data"] = resultLine;
                    joResult["state"] = false;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Console.Write(ex);
            }
            return joResult;
        }

        /// <summary>
        /// 取消点菜
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="dishesID"></param>
        /// <param name="date"></param>
        /// <param name="dbName"></param>
        /// <returns></returns>
        private JObject DelDishes(int userID, int dishesID, string date, string dbName)
        {
            JObject joResult = new JObject();
            try
            {
                int resultLine = 0;
                SqlCommand comm = new SqlCommand
                {
                    CommandText = "DELETE FROM UserDishes WHERE UserID = @UserID and DishesID = @DishesID and Date = @Date "
                };

                comm.Parameters.AddWithValue("@UserID", userID);
                comm.Parameters.AddWithValue("@DishesID", dishesID);
                comm.Parameters.AddWithValue("@Date", date);
                resultLine = pd.ExeSqlCode(comm, dbName);
                if (resultLine > 0)
                {
                    Console.Write("\n[" + date + "]: 数据库：" + dbName + "\n用户ID：" + userID + " 取消点菜成功，菜品ID：" + dishesID + "\n");
                    logger.Info("\n[" + date + "]: 数据库：" + dbName + "\n用户：" + userID + " 取消点菜成功，菜品ID：" + dishesID + "\n");

                    joResult["message"] = "取消点菜成功";
                    joResult["data"] = resultLine;
                    joResult["state"] = true;
                }
                else
                {
                    joResult["message"] = "取消点菜失败";
                    joResult["data"] = resultLine;
                    joResult["state"] = false;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Console.Write(ex);
            }
            return joResult;
        }

        /// <summary>
        /// 点菜操作
        /// </summary>
        /// <returns></returns>
        public JObject OptDishes(JObject joParam)
        {
            JObject joResult = new JObject();

            try
            {
                int userID = (int)joParam["userID"];
                string date = (string)joParam["date"];
                int districtID = (int)joParam["districtID"];
                int hallID = (int)joParam["hallID"];
                int dishesID = (int)joParam["dishesID"];
                int dishesClassID = (int)joParam["dishesClassID"];
                string deadLine = DateTime.Now.ToString("yyyy-MM-dd") + " " + (string)joParam["deadLine"];
                string currentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string remark = "";
                if (joParam.Property("remark") != null)
                {
                    remark = (string)joParam["remark"];
                }
                string dbName = bi.GetDBName(districtID);

                int resultLine = 0;
                SqlCommand comm = new SqlCommand();

                int UserDishesCount = CountUserDishes(userID, date, districtID, dishesClassID, dbName);
                int MaxDishesClassQty = MaxDishesClass(dishesClassID, dbName);

                bool isDishes = IsUserDishes(userID, date, districtID, dishesID, dishesClassID, dbName);

                if (Convert.ToDateTime(currentTime) < Convert.ToDateTime(deadLine))
                {
                    //已经点过菜了，则取消点菜
                    if (isDishes)
                    {
                        joResult = DelDishes(userID, dishesID, date, dbName);
                    }

                    //判断点菜数量是否达到类别最大值
                    if (UserDishesCount < MaxDishesClassQty)
                    {
                        //未点过菜，则发生点菜动作
                        if (!isDishes)
                        {
                            joResult = AddDishes(userID, dishesID, dishesClassID, date, districtID, hallID, remark, dbName);
                        }
                    }
                    //当前类别点菜数已经达到最大值且点了未点过的菜品时提示
                    else if (UserDishesCount >= MaxDishesClassQty && !isDishes)
                    {
                        Console.Write("\n[" + date + "]: 数据库：" + dbName + " 区域ID：" + districtID + "\n用户ID：" + userID + " 已完成类别：" + dishesClassID + " 的点菜，菜品ID：" + dishesID + " 点菜失败\n");
                        logger.Info("\n[" + date + "]: 数据库：" + dbName + " 区域ID：" + districtID + "\n用户ID：" + userID + " 已完成类别：" + dishesClassID + " 的点菜，菜品ID：" + dishesID + " 点菜失败\n");

                        joResult["message"] = "当前类别已点完菜了，点菜失败";
                        joResult["data"] = resultLine;
                        joResult["state"] = false;
                    }
                }
                else
                {
                    Console.Write("\n[" + date + "]: 数据库：" + dbName + " 区域ID：" + districtID + "\n用户ID：" + userID + " 类别ID：" + dishesClassID + " 菜品ID：" + dishesID + " 超过可点菜时间，点菜失败\n");
                    logger.Info("\n[" + date + "]: 数据库：" + dbName + " 区域ID：" + districtID + "\n用户ID：" + userID + " 类别ID：" + dishesClassID + " 菜品ID：" + dishesID + " 超过可点菜时间，点菜失败\n");

                    joResult["message"] = "超过有效点菜时间【" + (string)joParam["deadLine"] + "】，点菜失败";
                    joResult["data"] = resultLine;
                    joResult["state"] = false;
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                Console.Write(ex);
                joResult["data"] = 0;
                joResult["message"] = ex.Message + "\n" + ex.StackTrace;
                joResult["state"] = false;
            }

            return joResult;
        }
    }
}
